package org.laobai.permission.service.impl;

import org.laobai.permission.config.UserThreadLocal;
import org.laobai.permission.entity.Menu;
import org.laobai.permission.entity.RoleMenu;
import org.laobai.permission.entity.UserRole;
import org.laobai.permission.exception.PermissionException;
import org.laobai.permission.mapper.MenuMapper;
import org.laobai.permission.service.MenuService;
import org.laobai.permission.service.RoleMenuService;
import org.laobai.permission.service.UserRoleService;
import org.laobai.permission.struct.PageResult;
import org.laobai.permission.util.Asserts;
import org.laobai.permission.vo.SearchVO;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import sun.reflect.generics.tree.Tree;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author jiusan
 * @since 2021-11-17
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

    @Autowired
    private UserThreadLocal userThreadLocal;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private RoleMenuService roleMenuService;


    @Override
    public List<Menu> getTree() {
        // TODO
        // admin 放行
        Integer userId = userThreadLocal.getUser().getId();
        if(userId==1){
           return  getTree(list(),0);
        }


        // 获取角色IDs
        List<Integer> rids = userRoleService.list(new QueryWrapper<UserRole>().eq("uid", userId))
                .stream().map(UserRole::getRid).collect(Collectors.toList());

        if (CollectionUtils.isEmpty(rids)) {
            return Collections.EMPTY_LIST;
        }
        // 根据 角色IDs 查询菜单IDs
        Set<Integer> mids = roleMenuService.list(new QueryWrapper<RoleMenu>().in("rid", rids))
                .stream().map(RoleMenu::getMid).collect(Collectors.toSet());

        // 根据菜单ID查询菜单
        List<Menu> list = listByIds(mids);
        return getTree(list, 0);
    }

    @Override
    public boolean updateStatus(Integer menuId) {
        Menu menu = getById(menuId);
        menu.setEnabled(!menu.getEnabled());
        return updateMenu(menu);
    }


    @Override
    public PageResult<Menu> page(Integer currPage, Integer pageSize, SearchVO vo) {
        // 分页
        Page<Menu> menuPage = new Page<>(currPage, pageSize);

        // 条件查询
        QueryWrapper<Menu> wrapper = new QueryWrapper<>();

        if (Objects.nonNull(vo)) {
            String keyWord = vo.getKeyWord();
            if (!StringUtils.isEmpty(keyWord)) {
                wrapper.like("name", keyWord);
            }
        }
        menuPage = page(menuPage, wrapper);
        return PageResult.of(menuPage.getRecords(), menuPage.getTotal());
    }

    @Override
    public boolean saveMenu(Menu menu) {
        menu.setCreateTime(new Date());
//        if (StringUtils.isEmpty(menu.getName())) {
//            throw new PermissionException(4001, "名字不为空");
//        }
        Asserts.isNotNull(menu.getName(), 4001, "名字不为空");

        return save(menu);
    }

    @Override
    public boolean updateMenu(Menu menu) {
        return updateById(menu);
    }

    @Override
    public boolean delById(Long id) {
        return removeById(id);
    }

    @Override
    public boolean delByIds(List<Long> ids) {
        return removeByIds(ids);
    }


    /**
     * 递归遍历获取tree
     *
     * @param tree
     * @param pid
     * @return
     */
    private List<Menu> getTree(List<Menu> tree, Integer pid) {
        ArrayList<Menu> menus = new ArrayList<>();

        tree.forEach(item -> {
            if (item.getParentId().equals(pid)) {
                menus.add(item);
                // 递归调用 获取当前节点的子节点
                List<Menu> children = getTree(tree, item.getId());
                // 设置属性
                item.setChildren(children);
            }
        });
        return menus;
    }

}
